package com.bugman.business.impl;

import com.bugman.business.BugService;
import com.bugman.dao.Dao;
import com.bugman.entity.Bug;
import com.bugman.entity.Importance;
import com.bugman.entity.Project;
import com.bugman.entity.Status;
import com.bugman.filters.BugFilter;
import java.util.Date;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;

/**
 *
 * @author Flashman
 */
@Stateless
public class BugServiceBean extends BaseServiceBean implements BugService {

    @EJB
    Dao dao;

    /**
     * Vytvoří bug, nastaví mu datum vytovření, status na nový a důležitost
     * na neznámou. Následně jej uloží do databáze.
     *
     * @param bug   objekt ukládaného bugu
     */
    @RolesAllowed({"User", "Developer", "Admin"})
    public void createBug(Bug bug) {
        bug.setCreationTime(new Date());
        Status status = dao.getStatusById(Status.NEW);
        Importance importance = dao.getImportanceById(Importance.UNDECIDED);
        bug.setStatus(status);
        bug.setImportance(importance);
        dao.persist(bug);
    }

    /**
     * Změní objekt v bug v databázi podle objektu bugu daného parametrem
     *
     * @param bug   měněný bug
     */
    @RolesAllowed({"Developer", "Admin"})
    public void updateBug(Bug bug) {
        Byte statusId = bug.getStatus().getId();
        if (statusId == Status.FIXED || statusId == Status.INVALID ||
                statusId == Status.WONT_FIX) {
            bug.setResolvingTime(new Date());
        }
        dao.merge(bug);
    }

    /**
     * Smaže bug z databáze
     *
     * @param bug   mazaný bug
     */
    @RolesAllowed({"User", "Developer", "Admin"})
    public void deleteBug(Bug bug) {
        dao.remove(bug);
    }

    /**
     * Vrátí bug podle jeho ID v databázi
     *
     * @param bugId     ID bugu v databázi, který hledáme
     * @return Bug      vrácený bug z databáze
     */
    public Bug getBug(Integer bugId) {
        return dao.load(Bug.class, bugId);
    }

    /**
     * Vrátí seznam posledních bugů daných číslem count.
     *
     * @param count         počet posledních zadaných bugů
     * @return List<Bug>    seznam posledních bugů
     */
    public List<Bug> getLatestBugs(Integer count) {
        return dao.getLatestBugs(count);
    }

    /**
     * Vrátí seznam posledních bugů v projektu daných číslem count.
     *
     * @param project       projekt, u kterého hledáme bugy
     * @param count         počet posledních zadaných bugů u daného projektu
     * @return List<Bug>    seznam posledních bugů daného projektu
     */
    public List<Bug> getLatestBugs(Project project, Integer count) {
        return dao.getLatestProjectBugs(project, count);
    }

    /**
     * Vrátí vyfiltrovaný seznam bugů v projektu s maximální délkou count.
     *
     * @param filter        objekt obsahující filtrovací kritéria
     * @param count         maximální počet vrácených bugů
     * @return List<Bug>    filtrovaný seznam bugů
     */
    public List<Bug> getBugs(BugFilter filter, Integer count) {
        return dao.getBugs(filter.getStatus(), filter.getImportance(), count);
    }

    /**
     * Vrátí celkovy počet bugů.
     *
     * @return Integer      počet bugů v databázi
     */
    public Integer getAllBugsCount() {
        return dao.getBugsCount();
    }

    /**
     * Vrátí počet bugů přiřazených k zadanému projektu.
     *
     * @param project       projekt jehož bugy počítáme
     * @return Integer      počet bugů v projektu
     */
    public Integer getBugsCount(Project project) {
        return dao.getBugsCount(project);
    }

    /**
     * Vrátí seznam všech stavů.
     *
     * @return List<Status>    seznam všech stavů bugů
     */
    public List<Status> getAllStatuses() {
        return dao.getAllStatus();
    }

    /**
     * Vrátí status podle jeho ID v databázi
     *
     * @param statusId      ID statusu v databázi, který hledáme
     * @return Status       vrácený status z databáze
     */
    public Status getStatus(Byte statusId) {
        return dao.getStatusById(statusId);
    }

    /**
     * Vrátí seznam všech důležitostí.
     *
     * @return List<Importance>    seznam všech důležitostí bugů
     */
    public List<Importance> getAllImportances() {
        return dao.getAllImportance();
    }

    /**
     * Vrátí důležitost podle jeho ID v databázi
     *
     * @param importanceId      ID důležitosti v databázi, kterou hledáme
     * @return Importance       vrácená důležitost z databáze
     */
    public Importance getImportance(Byte importanceId) {
        return dao.getImportanceById(importanceId);
    }
}